/*
� 最佳准确率窗口:
{
  windowSize: 5,
  total: 1244,
  correct: 813,
  accuracy: 65.35,
  maxWrongStreak: 6
}

� 最小连续错误窗口:
{
  windowSize: 17,
  total: 1244,
  correct: 806,
  accuracy: 64.79,
  maxWrongStreak: 5
}
*/
// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

/**
 * ✨ 模运算策略（按遗漏期排序）
 * - 找出窗口内每个号码最近一次出现的位置
 * - 没出现的视为最大遗漏，优先选择这些号码
 */
function select32ByLongestOmission(temp) {
  const omissionMap = {};
  const len = temp.length;

  allNumbers.forEach((num) => {
    omissionMap[num] = len; // 初始化为窗口长度（表示从未出现）
  });

  for (let i = len - 1; i >= 0; i--) {
    const num = temp[i].number;
    if (omissionMap[num] === len) {
      omissionMap[num] = len - 1 - i;
    }
  }

  return Object.entries(omissionMap)
    .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
    .slice(0, 32)
    .map(([num]) => num);
}

// ✅ 存储每个窗口测试结果
const testResults = [];

for (let windowSize = 2; windowSize <= 200; windowSize++) {
  const predictResults = [];
  let correct = 0;
  let maxWrongStreak = 0;
  let currentWrongStreak = 0;

  for (let index = 0; index < allValues.length; index++) {
    const temp = allValues.slice(Math.max(0, index - windowSize), index);
    if (temp.length === 0) continue;

    const selectedNumbers = select32ByLongestOmission(temp);

    if (selectedNumbers.length !== 32) {
      throw new Error(`❗ 第 ${index} 期未能生成 32 个号码`);
    }

    const isHit = checkAccuracy(selectedNumbers, allValues[index].number);
    if (isHit) {
      correct++;
      currentWrongStreak = 0;
    } else {
      currentWrongStreak++;
      maxWrongStreak = Math.max(maxWrongStreak, currentWrongStreak);
    }

    predictResults.push(selectedNumbers);
  }

  const total = predictResults.length;
  const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : 0;

  testResults.push({
    windowSize,
    total,
    correct,
    accuracy: Number(accuracy),
    maxWrongStreak,
  });
}

// ✅ 输出所有窗口测试结果
testResults.forEach((res) => {
  console.log(
    `windowSize = ${res.windowSize}, 准确率 = ${res.accuracy}%, 最大连续错误次数 = ${res.maxWrongStreak}`
  );
});

// ✅ 输出最佳结果
const bestAcc = _.maxBy(testResults, "accuracy");
const bestStable = _.minBy(testResults, "maxWrongStreak");

console.log("\n🎯 最佳准确率窗口:");
console.log(bestAcc);
console.log("\n🧱 最小连续错误窗口:");
console.log(bestStable);
